package com.artisan.service.admin.impl;

import com.artisan.common.enums.OrderStateEnum2;
import com.artisan.common.utils.TimeFormatUtil;
import com.artisan.common.utils.wxpay.*;
import com.artisan.dao.CustomerOrderinfoMapper;
import com.artisan.dao.CustomerRefundinfoMapper;
import com.artisan.medium.admin.service.WxRefundService;
import com.artisan.model.CustomerOrderinfo;
import com.artisan.model.CustomerOrderinfoExample;
import com.artisan.model.CustomerRefundinfo;
import com.artisan.model.CustomerRefundinfoExample;
import com.sun.org.apache.bcel.internal.generic.RETURN;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.jdom.JDOMException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.transaction.Transactional;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * Created by szw on 2017/8/9.
 */
@Service("wxRefundService")
@Transactional
public class WxRefundServiceImpl implements WxRefundService {

	private static final Logger logger = LogManager.getLogger(WxRefundServiceImpl.class);

	@Autowired
	private CustomerOrderinfoMapper customerOrderinfoMapper;

	@Autowired
	private CustomerRefundinfoMapper customerRefundinfoMapper;

	/**
	 * 申请微信退款
	 * @param orderNo
	 */
	@Override
	public Map<String, String> refundMoney(String orderNo) {

		Map<String, String> resultMap = new HashMap<>();

		//订单信息
		CustomerOrderinfoExample orderinfoExample = new CustomerOrderinfoExample();
		CustomerOrderinfoExample.Criteria orderCriteria = orderinfoExample.createCriteria();
		orderCriteria.andOrderNoEqualTo(orderNo);
		List<CustomerOrderinfo> orderinfos =customerOrderinfoMapper.selectByExample(orderinfoExample);

		//退款信息
		CustomerRefundinfo refundinfo = null;
		CustomerRefundinfoExample refundinfoExample = new CustomerRefundinfoExample();
		CustomerRefundinfoExample.Criteria refundInfoCriteria = refundinfoExample.createCriteria();
		refundInfoCriteria.andOrderNoEqualTo(orderNo);
		List<CustomerRefundinfo> refundinfos = customerRefundinfoMapper.selectByExample(refundinfoExample);

		CustomerOrderinfo orderinfo = orderinfos.get(0);
		//订单总金额;将货币单位换算成分
		String total_fee = total_fee = String.valueOf(orderinfos.get(0).getMoney());
		if(total_fee.indexOf(".") > -1){
			total_fee = (Double.parseDouble(total_fee)*100+"").split("\\.")[0];
		}else{
			total_fee=Integer.parseInt(total_fee)*100+"";
		}

		if (refundinfos != null && refundinfos.size() > 0) {
			refundinfo = refundinfos.get(0);

		} else {
			refundinfo = new CustomerRefundinfo();
			refundinfo.setCrtTime(new Date());
			refundinfo.setOrderNo(orderinfo.getOrderNo());
			refundinfo.setUpdateTime(new Date());
			refundinfo.setRefundNo(generateRefundNo());

			Calendar c = Calendar.getInstance();
			c.setTime(orderinfo.getUpdateTime());
			c.add(Calendar.HOUR_OF_DAY, 2);

			long refundFee = 0l;
			if (orderinfo.getUpdateTime().before(orderinfo.getServiceTime()) && c.getTime().before(orderinfo.getServiceTime())) {
				refundFee = Long.valueOf(total_fee);
			} else {
				refundFee = Long.valueOf(total_fee) - 3000;
			}
			refundinfo.setRefundFee(refundFee);

			customerRefundinfoMapper.insert(refundinfo);
		}


		Map<String, String> refundMap = new HashMap<>();
		refundMap.put("appid", PayConfig.WeixinGZHPayConfig.APP_ID);
		refundMap.put("mch_id", PayConfig.WeixinGZHPayConfig.MACH_ID);
		refundMap.put("nonce_str", StringUtils.getCipher(12));
		refundMap.put("out_trade_no", orderNo);
		refundMap.put("out_refund_no", refundinfo.getRefundNo());
		refundMap.put("total_fee", total_fee);
		refundMap.put("refund_fee", String.valueOf(refundinfo.getRefundFee()));

		String sign = SignUtil.signMd5_2(refundMap, PayConfig.WeixinGZHPayConfig.KEY);
		refundMap.put("sign", sign);

		String createOrderURL = "https://api.mch.weixin.qq.com/secapi/pay/refund";
		String xml = null;
		xml = WxXmlUtil.ArrayToXml(refundMap);
		logger.debug("xml:" + xml);

		String retur = null;
		try {
			retur = ClientCustomSSL.doRefund(createOrderURL, xml);

			logger.info("Wechart refund interface returned result:" + retur);
		} catch (Exception e) {
			e.printStackTrace();
			logger.error("Exception happened when access wx refund interface:" + e.getMessage());
			resultMap.put("code", "FAIL");
			resultMap.put("msg", e.getMessage());
			return resultMap;
		}
		if (!StringUtils.isEmpty(retur)) {
			Map<String, String> map = null;
			try {
				map = XMLUtil.doXMLParse(retur);
			} catch (Exception e) {
				e.printStackTrace();
				logger.error("Transfer wx returned xml to map failed." + e.getMessage());
				resultMap.put("code", "FAIL");
				resultMap.put("msg", e.getMessage());
				return resultMap;
			}

			String returnCode = (String) map.get("return_code");
			if(returnCode.equals("SUCCESS")){

				int status = -1;
				String resultCode = (String)map.get("result_code");
				if(resultCode.equals("SUCCESS")){
					status = 1;
				}
				if(status == 1) {
					String outtradeno = (String) map.get("out_trade_no"); // 订单号
					String wxRefundId = (String)map.get("refund_id");
					refundinfo.setWxRefundId(wxRefundId);
					refundinfo.setUpdateTime(new Date());
					customerRefundinfoMapper.updateByPrimaryKeySelective(refundinfo);

					orderinfo.setUpdateTime(new Date());
					orderinfo.setState(OrderStateEnum2.IN_REFUND.getValue());
					customerOrderinfoMapper.updateByPrimaryKeySelective(orderinfo);
					resultMap.put("code", "SUCCESS");
					return resultMap;
					//业务操作
				} else {
					String errorCode = (String)map.get("err_code");
					String errorDesc = (String)map.get("err_code_des");
					logger.info(" 微信退款失败 errorCode = " + errorCode);
					logger.info(" 微信退款失败 errorDesc = " + errorDesc);
					resultMap.put("code", "FAIL");
					resultMap.put("msg", errorDesc);
					return resultMap;
				}
			} else {
				String msg = (String)map.get("return_msg");
				logger.info(" 微信退款失败 refundfail msg= " + msg);
				resultMap.put("code", "FAIL");
				resultMap.put("msg", msg);
				return resultMap;
			}

		}

		resultMap.put("code", "FAIL");
		resultMap.put("msg", "");
		return resultMap;
	}

	/**
	 * 生成退款单号
	 * @return
	 */
	private static String generateRefundNo() {
		String refundNo = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()) + ((int)((Math.random()*9+1)*100000));
		return refundNo;
	}


	@Override
	public void updateRefundStatus(String orderNo) {
		CustomerOrderinfoExample example = new CustomerOrderinfoExample();
		CustomerOrderinfoExample.Criteria criteria = example.createCriteria();
		criteria.andOrderNoEqualTo(orderNo);
		List<CustomerOrderinfo> orderinfos = customerOrderinfoMapper.selectByExample(example);

		if (orderinfos != null && orderinfos.size() > 0) {
			CustomerOrderinfo orderinfo = orderinfos.get(0);
			orderinfo.setUpdateTime(new Date());
			orderinfo.setState(OrderStateEnum2.REFUNDED.getValue());
			customerOrderinfoMapper.updateByPrimaryKeySelective(orderinfo);
		}
	}

	@Override
	public void updateOrderStatusByRefundResult(String orderNo) {
		CustomerOrderinfoExample example = new CustomerOrderinfoExample();
		CustomerOrderinfoExample.Criteria criteria = example.createCriteria();
		criteria.andOrderNoEqualTo(orderNo);
		List<CustomerOrderinfo> orderinfos = customerOrderinfoMapper.selectByExample(example);
		if (orderinfos != null && orderinfos.size() > 0) {
			CustomerOrderinfo orderinfo = orderinfos.get(0);
			orderinfo.setState(OrderStateEnum2.REFUNDED.getValue());
			orderinfo.setUpdateTime(new Date());
			customerOrderinfoMapper.updateByPrimaryKeySelective(orderinfo);
		}
	}
}
